/**
 * Created by huo on 2016/9/23.
 */
 function QMencrypt(plaintext, password)
 {
     if (plaintext.length == 0) return('');  // nothing to encrypt
     // 'escape' plaintext so chars outside ISO-8859-1 work in single-byte packing, but
     // keep spaces as spaces (not '%20') so encrypted text doesn't grow too long, and
     // convert result to longs
     var v = strToLongs(escape(plaintext).replace(/%20/g,' '));
     if (v.length <= 1) v[1] = 0;  // algorithm doesn't work for n<2 so fudge by adding nulls
 
     // will(a)ndri.st: make password become a SHA 1 Hash of itself
     password = do_sha1(password);
     var k = strToLongs(password.slice(0,16));  // simply convert first 16 chars of password as key
     var n = v.length;
 
     var z = v[n-1], y = v[0], delta = 0x9E3779B9;
     //var mx, e, q = Math.floor(6 + 52/n), sum = 0;
     var mx, e, q = Math.floor(16 + 52/n), sum = 0;   // WA: increase encryption level by extending rounds from former 6 to 16
 
     while (q-- > 0) {  // 6 + 52/n operations gives between 6 & 32 mixes on each word
         sum += delta;
         e = sum>>>2 & 3;
         for (var p = 0; p < n-1; p++) {
             y = v[p+1];
             mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
             z = v[p] += mx;
         }
         y = v[0];
         mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
         z = v[n-1] += mx;
     }
     // note use of >>> in place of >> due to lack of 'unsigned' type in JavaScript
     // (thanks to Karsten Kraus @ swr3 for this)
 
     result = (longsToStr(v));
     // added by WA: Output is expected to be in Base64 encoding to support pocket Note formatting.
     return encodeBase64(result);
 
 }
 
 function QMdecrypt(ciphertext, password)
 {
     // added by WA: Choose encrypted text from URL instead of input field
     var URLwert = do_URLcontent("" + document.URL);
     if (URLwert == "-") {
         ciphertext = ciphertext;
     } else {
         ciphertext = URLwert;
     }
     if (ciphertext.length == 0) return('');
 
     // added by WA: Input is expected to be in Base64 encoding
     ciphertext = decodeBase64(ciphertext)
     var v = strToLongs(unescCtrlCh(ciphertext));
 
     // will(a)ndri.st: make password become a SHA 1 Hash of itself;
     password = do_sha1(password);
 
     var k = strToLongs(password.slice(0,16));
     var n = v.length;
 
     var z = v[n-1], y = v[0], delta = 0x9E3779B9;
     //    var mx, e, q = Math.floor(6 + 52/n), sum = q*delta;
     var mx, e, q = Math.floor(16 + 52/n), sum = q*delta;     /// increased security by changing from 6 to 16. Might become 3times slower though
 
     while (sum != 0) {
         e = sum>>>2 & 3;
         for (var p = n-1; p > 0; p--) {
             z = v[p-1];
             mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
             y = v[p] -= mx;
         }
         z = v[n-1];
         mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z)
         y = v[0] -= mx;
         sum -= delta;
     }
 
     var plaintext = longsToStr(v);
     // strip trailing null chars resulting from filling 4-char blocks:
     if (plaintext.search(/\0/) != -1) plaintext = plaintext.slice(0, plaintext.search(/\0/));
     return unescape(plaintext);
 }
 
 
 // supporting functions
 
 function strToLongs(s) {  // convert string to array of longs, each containing 4 chars
     // note chars must be within ISO-8859-1 (with Unicode code-point < 256) to fit 4/long
     var l = new Array(Math.ceil(s.length/4))
     for (var i=0; i<l.length; i++) {
         // note little-endian encoding - endianness is irrelevant as long as
         // it is the same in longsToStr()
         l[i] = s.charCodeAt(i*4) + (s.charCodeAt(i*4+1)<<8) +
             (s.charCodeAt(i*4+2)<<16) + (s.charCodeAt(i*4+3)<<24);
     }
     return l;  // note running off the end of the string generates nulls since
 }              // bitwise operators treat NaN as 0
 
 function longsToStr(l) {  // convert array of longs back to string
     var a = new Array(l.length);
     for (var i=0; i<l.length; i++) {
         a[i] = String.fromCharCode(l[i] & 0xFF, l[i]>>>8 & 0xFF,
             l[i]>>>16 & 0xFF, l[i]>>>24 & 0xFF);
     }
     return a.join('');  // use Array.join() rather than repeated string appends for efficiency
 }
 
 function escCtrlCh(str) {  // escape control chars which might cause problems with encrypted texts
     return str.replace(/[\0\n\v\f\r!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; });
 }
 
 function unescCtrlCh(str) {  // unescape potentially problematic nulls and control characters
     return str.replace(/!\d\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); });
 }
 
 // -----------------
 // Read URL: Detect content of encrypted test, starting after  ...htm?e=....
 // added by WA
 // -----------------
 function do_URLcontent(URLx)
 {
     fullurl = URLx;
     if (fullurl.indexOf('?') > 0) {
         URLx = fullurl.substring(fullurl.indexOf('?')+3, fullurl.length);
     } else {
         URLx = "-";
     }
     return (URLx);
 }
 
 
 //--------------------------------------------------
 // Hex64Base for Cipher Text to prevent Unicode conversion Problems
 // added by will(a)ndri.st, source ostermiller.org
 //-------------------------------------------------
 var END_OF_INPUT = -1;
 
 var base64Chars = new Array(
     'A','B','C','D','E','F','G','H',
     'I','J','K','L','M','N','O','P',
     'Q','R','S','T','U','V','W','X',
     'Y','Z','a','b','c','d','e','f',
     'g','h','i','j','k','l','m','n',
     'o','p','q','r','s','t','u','v',
     'w','x','y','z','0','1','2','3',
     '4','5','6','7','8','9','+','/'
 );
 
 var reverseBase64Chars = new Array();
 for (var i=0; i < base64Chars.length; i++){
     reverseBase64Chars[base64Chars[i]] = i;
 }
 
 var base64Str;
 var base64Count;
 function setBase64Str(str){
     base64Str = str;
     base64Count = 0;
 }
 function readBase64(){
     if (!base64Str) return END_OF_INPUT;
     if (base64Count >= base64Str.length) return END_OF_INPUT;
     var c = base64Str.charCodeAt(base64Count) & 0xff;
     base64Count++;
     return c;
 }
 function encodeBase64(str){
     setBase64Str(str);
     var result = '';
     var inBuffer = new Array(3);
     var lineCount = 0;
     var done = false;
     while (!done && (inBuffer[0] = readBase64()) != END_OF_INPUT){
         inBuffer[1] = readBase64();
         inBuffer[2] = readBase64();
         result += (base64Chars[ inBuffer[0] >> 2 ]);
         if (inBuffer[1] != END_OF_INPUT){
             result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30) | (inBuffer[1] >> 4) ]);
             if (inBuffer[2] != END_OF_INPUT){
                 result += (base64Chars [((inBuffer[1] << 2) & 0x3c) | (inBuffer[2] >> 6) ]);
                 result += (base64Chars [inBuffer[2] & 0x3F]);
             } else {
                 result += (base64Chars [((inBuffer[1] << 2) & 0x3c)]);
                 result += ('=');
                 done = true;
             }
         } else {
             result += (base64Chars [(( inBuffer[0] << 4 ) & 0x30)]);
             result += ('=');
             result += ('=');
             done = true;
         }
         lineCount += 4;
         if (lineCount >= 76){
             result += ('\n');
             lineCount = 0;
         }
     }
     return result;
 }
 function readReverseBase64(){
     if (!base64Str) return END_OF_INPUT;
     while (true){
         if (base64Count >= base64Str.length) return END_OF_INPUT;
         var nextCharacter = base64Str.charAt(base64Count);
         base64Count++;
         if (reverseBase64Chars[nextCharacter]){
             return reverseBase64Chars[nextCharacter];
         }
         if (nextCharacter == 'A') return 0;
     }
     return END_OF_INPUT;
 }
 
 function ntos(n){
     n=n.toString(16);
     if (n.length == 1) n="0"+n;
     n="%"+n;
     return unescape(n);
 }
 
 function decodeBase64(str){
     setBase64Str(str);
     var result = "";
     var inBuffer = new Array(4);
     var done = false;
     while (!done && (inBuffer[0] = readReverseBase64()) != END_OF_INPUT
     && (inBuffer[1] = readReverseBase64()) != END_OF_INPUT){
         inBuffer[2] = readReverseBase64();
         inBuffer[3] = readReverseBase64();
         result += ntos((((inBuffer[0] << 2) & 0xff)| inBuffer[1] >> 4));
         if (inBuffer[2] != END_OF_INPUT){
             result +=  ntos((((inBuffer[1] << 4) & 0xff)| inBuffer[2] >> 2));
             if (inBuffer[3] != END_OF_INPUT){
                 result +=  ntos((((inBuffer[2] << 6)  & 0xff) | inBuffer[3]));
             } else {
                 done = true;
             }
         } else {
             done = true;
         }
     }
     return result;
 }
 
 //--------------------------------------------------
 // Hex in Unicode - changes SHA-1 Hash result from two digit Hex in single characters
 // added by WA, source ostermiller.org
 //-------------------------------------------------
 
 function decodeHex(str){
     str = str.replace(new RegExp("s/[^0-9a-zA-Z]//g"));
     var result = "";
     var nextchar = "";
     for (var i=0; i<str.length; i++){
         nextchar += str.charAt(i);
         if (nextchar.length == 2){
             result += ntos(eval('0x'+nextchar));
             nextchar = "";
         }
     }
     return result;
 
 }
 
 
 
 //----------------------------------
 // SHA-1
 // added by will(a)ndri.st, source by ostermiller.org
 //----------------------------------
 
 // accumulate values to put into text area
 var accumulated_output_info;
 
 // add a labeled value to the text area
 function accumulate_output( str )
 {
     accumulated_output_info = accumulated_output_info + str + "\n";
 }
 
 // convert a 32-bit value to a 8-char hex string
 function cvt_hex( val )
 {
     var str="";
     var i;
     var v;
 
     for( i=7; i>=0; i-- )
     {
         v = (val>>>(i*4))&0x0f;
         str += v.toString(16);
     }
     return str;
 }
 
 // add a bit string to the output, inserting spaces as designated
 function accumulate_val( label, val )
 {
     accumulated_output_info += label + cvt_hex(val) + "\n";
 }
 
 // return a hex value LSB first
 function lsb_hex( val )
 {
     var str="";
     var i;
     var vh;
     var vl;
 
     for( i=0; i<=6; i+=2 )
     {
         vh = (val>>>(i*4+4))&0x0f;
         vl = (val>>>(i*4))&0x0f;
         str += vh.toString(16) + vl.toString(16);
     }
     return str;
 }
 
 // rotate left circular
 function rotate_left( n, s )
 {
     var t4 = ( n<<s ) | (n>>>(32-s));
 //   accumulate_output( "  "+cvt_hex(n)+"<<<"+s+"="+cvt_hex(t4) );
     return t4;
 }
 
 // calculate the hash
 function do_sha1(msg)
 {
     var blockstart;			// which block of words from the dataare we using now?
     var i, j;
     var W = new Array(80);
     // initial constants
     var H0 = 0x67452301;
     var H1 = 0xEFCDAB89;
     var H2 = 0x98BADCFE;
     var H3 = 0x10325476;
     var H4 = 0xC3D2E1F0;
     // working variables
     var A, B, C, D, E;
     var temp;
 
     // initialize detail output string
     accumulated_output_info="";
 
     // get message to hash
     //var msg = document.stuff.inmsg.value;
 
     // note current length
     var msg_len = msg.length;
 
     // convert to a 32-bit word array
     var word_array = new Array();
     for( i=0; i<msg_len-3; i+=4 )
     {
         // convert 4 bytes to a word
         j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 |
             msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3);
         word_array.push( j );
         accumulate_val( msg.substr(i, 4)+": ", j );
     }
 
     // handle final bits, add beginning of padding: 1 bit, then 0 bits
     switch( msg_len % 4 )
     {
         case 0:
             // text length was a multiple of 4 bytes, start padding
             i = 0x080000000;				// 4 bytes padding
             break;
 
         case 1:
             // one byte of text left
             i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000;	// 3 bytes padding
             break;
 
         case 2:
             // two bytes of text left
             i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16
                 | 0x08000;				// 2 bytes padding
             break;
 
         case 3:
             // three bytes of text left
             i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16
                 | msg.charCodeAt(msg_len-1)<<8	| 0x80;	// 1 byte padding
             break;
 
         default:
             window.alert("Something went weird in the switch!")
             return;
     }
     accumulate_output( "length="+msg_len );
     accumulate_val( "length%4="+(msg_len%4)+", padding=", i );
 
     // handle the end of the text and beginning of the padding
     word_array.push( i );
 
     // pad to 448 bits (mod 512 bits) = 14 words (mod 16 words)
     while( (word_array.length % 16) != 14 )
         word_array.push( 0 );
 
     // add 64-bit message length (in bits)
     word_array.push( msg_len>>>29 );
     word_array.push( (msg_len<<3)&0x0ffffffff );
 
     for( i=0; i<word_array.length; i++ )
         accumulate_output( "msg[" + i + "]=" + cvt_hex( word_array[i] ) );
 
     // Process each 16-word block.
     for ( blockstart=0; blockstart<word_array.length; blockstart+=16 )
     {
         accumulate_output( "Starting block at word "+blockstart );
 
         // create entries in W array
         for( i=0; i<16; i++ )
             W[i] = word_array[blockstart+i];
         for( i=16; i<=79; i++ )
             W[i] = rotate_left(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
         for( i=0; i<=79; i++ )
             accumulate_output( "W[" + i + "]=" + cvt_hex( W[i] ) );
 
         // copy state
         A = H0;
         B = H1;
         C = H2;
         D = H3;
         E = H4;
 
         // note start of round values
         accumulate_output("A=" + cvt_hex(A) + " B=" + cvt_hex(B) + " C=" + cvt_hex(C)
             + " D=" + cvt_hex(D) + " E=" + cvt_hex(E) );
 
         // update state variables
         for( i= 0; i<=19; i++ )
         {
             temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
 
             // update state
             E = D;
             D = C;
             C = rotate_left(B,30);
             B = A;
             A = temp;
             accumulate_output( "i="+i+" A=" + cvt_hex(A) + " B=" + cvt_hex(B) + " C=" + cvt_hex(C)
                 + " D=" + cvt_hex(D) + " E=" + cvt_hex(E) );
         }
 
         for( i=20; i<=39; i++ )
         {
             temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
 
             // update state
             E = D;
             D = C;
             C = rotate_left(B,30);
             B = A;
             A = temp;
             accumulate_output( "i="+i+" A=" + cvt_hex(A) + " B=" + cvt_hex(B) + " C=" + cvt_hex(C)
                 + " D=" + cvt_hex(D) + " E=" + cvt_hex(E) );
         }
 
         for( i=40; i<=59; i++ )
         {
             temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
 
             // update state
             E = D;
             D = C;
             C = rotate_left(B,30);
             B = A;
             A = temp;
             accumulate_output( "i="+i+" A=" + cvt_hex(A) + " B=" + cvt_hex(B) + " C=" + cvt_hex(C)
                 + " D=" + cvt_hex(D) + " E=" + cvt_hex(E) );
         }
 
         for( i=60; i<=79; i++ )
         {
             temp = (rotate_left(A,5) + (B ^ C ^ D) + E + W[i] + 0x6CA62C1D6) & 0x0ffffffff;
 
             // update state
             E = D;
             D = C;
             C = rotate_left(B,30);
             B = A;
             A = temp;
             accumulate_output( "i="+i+" A=" + cvt_hex(A) + " B=" + cvt_hex(B) + " C=" + cvt_hex(C)
                 + " D=" + cvt_hex(D) + " E=" + cvt_hex(E) );
         }
 
         H0 = (H0 + A) & 0x0ffffffff;
         H1 = (H1 + B) & 0x0ffffffff;
         H2 = (H2 + C) & 0x0ffffffff;
         H3 = (H3 + D) & 0x0ffffffff;
         H4 = (H4 + E) & 0x0ffffffff;
 
         accumulate_output( "H0=" + cvt_hex(H0) + " H1=" + cvt_hex(H1) + " H2=" + cvt_hex(H2)
             + " H3=" + cvt_hex(H3) + " H4=" + cvt_hex(H4) );
     } // of loop on i
 
     // process output
     // document.stuff.outhash.value = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
     // document.stuff.details.value = accumulated_output_info;
     result = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
 
     // will(a)ndri.st returns two digit hex code into unicode single characters
     return decodeHex(result);
 }
 /*
  QMCJS v3.1.2
  code.google.com/p/crypto-js
  (c) 2009-2013 by Jeff Mott. All rights reserved.
  code.google.com/p/crypto-js/wiki/License
  */
 var QMCJS = QMCJS || function(u, p) {
         var d = {}, l = d.lib = {}, s = function() {}, t = l.Base = {
             extend:function(a) {
                 s.prototype = this;
                 var c = new s();
                 a && c.mixIn(a);
                 c.hasOwnProperty("init") || (c.init = function() {
                     c.$super.init.apply(this, arguments);
                 });
                 c.init.prototype = c;
                 c.$super = this;
                 return c;
             },
             create:function() {
                 var a = this.extend();
                 a.init.apply(a, arguments);
                 return a;
             },
             init:function() {},
             mixIn:function(a) {
                 for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]);
                 a.hasOwnProperty("toString") && (this.toString = a.toString);
             },
             clone:function() {
                 return this.init.prototype.extend(this);
             }
         }, r = l.WordArray = t.extend({
             init:function(a, c) {
                 a = this.words = a || [];
                 this.sigBytes = c != p ? c :4 * a.length;
             },
             toString:function(a) {
                 return (a || v).stringify(this);
             },
             concat:function(a) {
                 var c = this.words, e = a.words, j = this.sigBytes;
                 a = a.sigBytes;
                 this.clamp();
                 if (j % 4) for (var k = 0; k < a; k++) c[j + k >>> 2] |= (e[k >>> 2] >>> 24 - 8 * (k % 4) & 255) << 24 - 8 * ((j + k) % 4); else if (65535 < e.length) for (k = 0; k < a; k += 4) c[j + k >>> 2] = e[k >>> 2]; else c.push.apply(c, e);
                 this.sigBytes += a;
                 return this;
             },
             clamp:function() {
                 var a = this.words, c = this.sigBytes;
                 a[c >>> 2] &= 4294967295 << 32 - 8 * (c % 4);
                 a.length = u.ceil(c / 4);
             },
             clone:function() {
                 var a = t.clone.call(this);
                 a.words = this.words.slice(0);
                 return a;
             },
             random:function(a) {
                 for (var c = [], e = 0; e < a; e += 4) c.push(4294967296 * u.random() | 0);
                 return new r.init(c, a);
             }
         }), w = d.enc = {}, v = w.Hex = {
             stringify:function(a) {
                 var c = a.words;
                 a = a.sigBytes;
                 for (var e = [], j = 0; j < a; j++) {
                     var k = c[j >>> 2] >>> 24 - 8 * (j % 4) & 255;
                     e.push((k >>> 4).toString(16));
                     e.push((k & 15).toString(16));
                 }
                 return e.join("");
             },
             parse:function(a) {
                 for (var c = a.length, e = [], j = 0; j < c; j += 2) e[j >>> 3] |= parseInt(a.substr(j, 2), 16) << 24 - 4 * (j % 8);
                 return new r.init(e, c / 2);
             }
         }, b = w.Latin1 = {
             stringify:function(a) {
                 var c = a.words;
                 a = a.sigBytes;
                 for (var e = [], j = 0; j < a; j++) e.push(String.fromCharCode(c[j >>> 2] >>> 24 - 8 * (j % 4) & 255));
                 return e.join("");
             },
             parse:function(a) {
                 for (var c = a.length, e = [], j = 0; j < c; j++) e[j >>> 2] |= (a.charCodeAt(j) & 255) << 24 - 8 * (j % 4);
                 return new r.init(e, c);
             }
         }, x = w.Utf8 = {
             stringify:function(a) {
                 try {
                     return decodeURIComponent(escape(b.stringify(a)));
                 } catch (c) {
                     throw Error("Malformed UTF-8 data");
                 }
             },
             parse:function(a) {
                 return b.parse(unescape(encodeURIComponent(a)));
             }
         }, q = l.BufferedBlockAlgorithm = t.extend({
             reset:function() {
                 this._data = new r.init();
                 this._nDataBytes = 0;
             },
             _append:function(a) {
                 "string" == typeof a && (a = x.parse(a));
                 this._data.concat(a);
                 this._nDataBytes += a.sigBytes;
             },
             _process:function(a) {
                 var c = this._data, e = c.words, j = c.sigBytes, k = this.blockSize, b = j / (4 * k), b = a ? u.ceil(b) :u.max((b | 0) - this._minBufferSize, 0);
                 a = b * k;
                 j = u.min(4 * a, j);
                 if (a) {
                     for (var q = 0; q < a; q += k) this._doProcessBlock(e, q);
                     q = e.splice(0, a);
                     c.sigBytes -= j;
                 }
                 return new r.init(q, j);
             },
             clone:function() {
                 var a = t.clone.call(this);
                 a._data = this._data.clone();
                 return a;
             },
             _minBufferSize:0
         });
         l.Hasher = q.extend({
             cfg:t.extend(),
             init:function(a) {
                 this.cfg = this.cfg.extend(a);
                 this.reset();
             },
             reset:function() {
                 q.reset.call(this);
                 this._doReset();
             },
             update:function(a) {
                 this._append(a);
                 this._process();
                 return this;
             },
             finalize:function(a) {
                 a && this._append(a);
                 return this._doFinalize();
             },
             blockSize:16,
             _createHelper:function(a) {
                 return function(b, e) {
                     return new a.init(e).finalize(b);
                 };
             },
             _createHmacHelper:function(a) {
                 return function(b, e) {
                     return new n.HMAC.init(a, e).finalize(b);
                 };
             }
         });
         var n = d.algo = {};
         return d;
     }(Math);
 
 (function() {
     var u = QMCJS, p = u.lib.WordArray;
     u.enc.Base64 = {
         stringify:function(d) {
             var l = d.words, p = d.sigBytes, t = this._map;
             d.clamp();
             d = [];
             for (var r = 0; r < p; r += 3) for (var w = (l[r >>> 2] >>> 24 - 8 * (r % 4) & 255) << 16 | (l[r + 1 >>> 2] >>> 24 - 8 * ((r + 1) % 4) & 255) << 8 | l[r + 2 >>> 2] >>> 24 - 8 * ((r + 2) % 4) & 255, v = 0; 4 > v && r + .75 * v < p; v++) d.push(t.charAt(w >>> 6 * (3 - v) & 63));
             if (l = t.charAt(64)) for (;d.length % 4; ) d.push(l);
             return d.join("");
         },
         parse:function(d) {
             var l = d.length, s = this._map, t = s.charAt(64);
             t && (t = d.indexOf(t), -1 != t && (l = t));
             for (var t = [], r = 0, w = 0; w < l; w++) if (w % 4) {
                 var v = s.indexOf(d.charAt(w - 1)) << 2 * (w % 4), b = s.indexOf(d.charAt(w)) >>> 6 - 2 * (w % 4);
                 t[r >>> 2] |= (v | b) << 24 - 8 * (r % 4);
                 r++;
             }
             return p.create(t, r);
         },
         _map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
     };
 })();
 
 (function(u) {
     function p(b, n, a, c, e, j, k) {
         b = b + (n & a | ~n & c) + e + k;
         return (b << j | b >>> 32 - j) + n;
     }
     function d(b, n, a, c, e, j, k) {
         b = b + (n & c | a & ~c) + e + k;
         return (b << j | b >>> 32 - j) + n;
     }
     function l(b, n, a, c, e, j, k) {
         b = b + (n ^ a ^ c) + e + k;
         return (b << j | b >>> 32 - j) + n;
     }
     function s(b, n, a, c, e, j, k) {
         b = b + (a ^ (n | ~c)) + e + k;
         return (b << j | b >>> 32 - j) + n;
     }
     for (var t = QMCJS, r = t.lib, w = r.WordArray, v = r.Hasher, r = t.algo, b = [], x = 0; 64 > x; x++) b[x] = 4294967296 * u.abs(u.sin(x + 1)) | 0;
     r = r.MD5 = v.extend({
         _doReset:function() {
             this._hash = new w.init([ 1732584193, 4023233417, 2562383102, 271733878 ]);
         },
         _doProcessBlock:function(q, n) {
             for (var a = 0; 16 > a; a++) {
                 var c = n + a, e = q[c];
                 q[c] = (e << 8 | e >>> 24) & 16711935 | (e << 24 | e >>> 8) & 4278255360;
             }
             var a = this._hash.words, c = q[n + 0], e = q[n + 1], j = q[n + 2], k = q[n + 3], z = q[n + 4], r = q[n + 5], t = q[n + 6], w = q[n + 7], v = q[n + 8], A = q[n + 9], B = q[n + 10], C = q[n + 11], u = q[n + 12], D = q[n + 13], E = q[n + 14], x = q[n + 15], f = a[0], m = a[1], g = a[2], h = a[3], f = p(f, m, g, h, c, 7, b[0]), h = p(h, f, m, g, e, 12, b[1]), g = p(g, h, f, m, j, 17, b[2]), m = p(m, g, h, f, k, 22, b[3]), f = p(f, m, g, h, z, 7, b[4]), h = p(h, f, m, g, r, 12, b[5]), g = p(g, h, f, m, t, 17, b[6]), m = p(m, g, h, f, w, 22, b[7]), f = p(f, m, g, h, v, 7, b[8]), h = p(h, f, m, g, A, 12, b[9]), g = p(g, h, f, m, B, 17, b[10]), m = p(m, g, h, f, C, 22, b[11]), f = p(f, m, g, h, u, 7, b[12]), h = p(h, f, m, g, D, 12, b[13]), g = p(g, h, f, m, E, 17, b[14]), m = p(m, g, h, f, x, 22, b[15]), f = d(f, m, g, h, e, 5, b[16]), h = d(h, f, m, g, t, 9, b[17]), g = d(g, h, f, m, C, 14, b[18]), m = d(m, g, h, f, c, 20, b[19]), f = d(f, m, g, h, r, 5, b[20]), h = d(h, f, m, g, B, 9, b[21]), g = d(g, h, f, m, x, 14, b[22]), m = d(m, g, h, f, z, 20, b[23]), f = d(f, m, g, h, A, 5, b[24]), h = d(h, f, m, g, E, 9, b[25]), g = d(g, h, f, m, k, 14, b[26]), m = d(m, g, h, f, v, 20, b[27]), f = d(f, m, g, h, D, 5, b[28]), h = d(h, f, m, g, j, 9, b[29]), g = d(g, h, f, m, w, 14, b[30]), m = d(m, g, h, f, u, 20, b[31]), f = l(f, m, g, h, r, 4, b[32]), h = l(h, f, m, g, v, 11, b[33]), g = l(g, h, f, m, C, 16, b[34]), m = l(m, g, h, f, E, 23, b[35]), f = l(f, m, g, h, e, 4, b[36]), h = l(h, f, m, g, z, 11, b[37]), g = l(g, h, f, m, w, 16, b[38]), m = l(m, g, h, f, B, 23, b[39]), f = l(f, m, g, h, D, 4, b[40]), h = l(h, f, m, g, c, 11, b[41]), g = l(g, h, f, m, k, 16, b[42]), m = l(m, g, h, f, t, 23, b[43]), f = l(f, m, g, h, A, 4, b[44]), h = l(h, f, m, g, u, 11, b[45]), g = l(g, h, f, m, x, 16, b[46]), m = l(m, g, h, f, j, 23, b[47]), f = s(f, m, g, h, c, 6, b[48]), h = s(h, f, m, g, w, 10, b[49]), g = s(g, h, f, m, E, 15, b[50]), m = s(m, g, h, f, r, 21, b[51]), f = s(f, m, g, h, u, 6, b[52]), h = s(h, f, m, g, k, 10, b[53]), g = s(g, h, f, m, B, 15, b[54]), m = s(m, g, h, f, e, 21, b[55]), f = s(f, m, g, h, v, 6, b[56]), h = s(h, f, m, g, x, 10, b[57]), g = s(g, h, f, m, t, 15, b[58]), m = s(m, g, h, f, D, 21, b[59]), f = s(f, m, g, h, z, 6, b[60]), h = s(h, f, m, g, C, 10, b[61]), g = s(g, h, f, m, j, 15, b[62]), m = s(m, g, h, f, A, 21, b[63]);
             a[0] = a[0] + f | 0;
             a[1] = a[1] + m | 0;
             a[2] = a[2] + g | 0;
             a[3] = a[3] + h | 0;
         },
         _doFinalize:function() {
             var b = this._data, n = b.words, a = 8 * this._nDataBytes, c = 8 * b.sigBytes;
             n[c >>> 5] |= 128 << 24 - c % 32;
             var e = u.floor(a / 4294967296);
             n[(c + 64 >>> 9 << 4) + 15] = (e << 8 | e >>> 24) & 16711935 | (e << 24 | e >>> 8) & 4278255360;
             n[(c + 64 >>> 9 << 4) + 14] = (a << 8 | a >>> 24) & 16711935 | (a << 24 | a >>> 8) & 4278255360;
             b.sigBytes = 4 * (n.length + 1);
             this._process();
             b = this._hash;
             n = b.words;
             for (a = 0; 4 > a; a++) c = n[a], n[a] = (c << 8 | c >>> 24) & 16711935 | (c << 24 | c >>> 8) & 4278255360;
             return b;
         },
         clone:function() {
             var b = v.clone.call(this);
             b._hash = this._hash.clone();
             return b;
         }
     });
     t.MD5 = v._createHelper(r);
     t.HmacMD5 = v._createHmacHelper(r);
 })(Math);
 
 (function() {
     var u = QMCJS, p = u.lib, d = p.Base, l = p.WordArray, p = u.algo, s = p.EvpKDF = d.extend({
         cfg:d.extend({
             keySize:4,
             hasher:p.MD5,
             iterations:1
         }),
         init:function(d) {
             this.cfg = this.cfg.extend(d);
         },
         compute:function(d, r) {
             for (var p = this.cfg, s = p.hasher.create(), b = l.create(), u = b.words, q = p.keySize, p = p.iterations; u.length < q; ) {
                 n && s.update(n);
                 var n = s.update(d).finalize(r);
                 s.reset();
                 for (var a = 1; a < p; a++) n = s.finalize(n), s.reset();
                 b.concat(n);
             }
             b.sigBytes = 4 * q;
             return b;
         }
     });
     u.EvpKDF = function(d, l, p) {
         return s.create(p).compute(d, l);
     };
 })();
 
 QMCJS.lib.Cipher || function(u) {
     var p = QMCJS, d = p.lib, l = d.Base, s = d.WordArray, t = d.BufferedBlockAlgorithm, r = p.enc.Base64, w = p.algo.EvpKDF, v = d.Cipher = t.extend({
         cfg:l.extend(),
         createEncryptor:function(e, a) {
             return this.create(this._ENC_XFORM_MODE, e, a);
         },
         createDecryptor:function(e, a) {
             return this.create(this._DEC_XFORM_MODE, e, a);
         },
         init:function(e, a, b) {
             this.cfg = this.cfg.extend(b);
             this._xformMode = e;
             this._key = a;
             this.reset();
         },
         reset:function() {
             t.reset.call(this);
             this._doReset();
         },
         process:function(e) {
             this._append(e);
             return this._process();
         },
         finalize:function(e) {
             e && this._append(e);
             return this._doFinalize();
         },
         keySize:4,
         ivSize:4,
         _ENC_XFORM_MODE:1,
         _DEC_XFORM_MODE:2,
         _createHelper:function(e) {
             return {
                 encrypt:function(b, k, d) {
                     return ("string" == typeof k ? c :a).encrypt(e, b, k, d);
                 },
                 decrypt:function(b, k, d) {
                     return ("string" == typeof k ? c :a).decrypt(e, b, k, d);
                 }
             };
         }
     });
     d.StreamCipher = v.extend({
         _doFinalize:function() {
             return this._process(!0);
         },
         blockSize:1
     });
     var b = p.mode = {}, x = function(e, a, b) {
         var c = this._iv;
         c ? this._iv = u :c = this._prevBlock;
         for (var d = 0; d < b; d++) e[a + d] ^= c[d];
     }, q = (d.BlockCipherMode = l.extend({
         createEncryptor:function(e, a) {
             return this.Encryptor.create(e, a);
         },
         createDecryptor:function(e, a) {
             return this.Decryptor.create(e, a);
         },
         init:function(e, a) {
             this._cipher = e;
             this._iv = a;
         }
     })).extend();
     q.Encryptor = q.extend({
         processBlock:function(e, a) {
             var b = this._cipher, c = b.blockSize;
             x.call(this, e, a, c);
             b.encryptBlock(e, a);
             this._prevBlock = e.slice(a, a + c);
         }
     });
     q.Decryptor = q.extend({
         processBlock:function(e, a) {
             var b = this._cipher, c = b.blockSize, d = e.slice(a, a + c);
             b.decryptBlock(e, a);
             x.call(this, e, a, c);
             this._prevBlock = d;
         }
     });
     b = b.CBC = q;
     q = (p.pad = {}).Pkcs7 = {
         pad:function(a, b) {
             for (var c = 4 * b, c = c - a.sigBytes % c, d = c << 24 | c << 16 | c << 8 | c, l = [], n = 0; n < c; n += 4) l.push(d);
             c = s.create(l, c);
             a.concat(c);
         },
         unpad:function(a) {
             a.sigBytes -= a.words[a.sigBytes - 1 >>> 2] & 255;
         }
     };
     d.BlockCipher = v.extend({
         cfg:v.cfg.extend({
             mode:b,
             padding:q
         }),
         reset:function() {
             v.reset.call(this);
             var a = this.cfg, b = a.iv, a = a.mode;
             if (this._xformMode == this._ENC_XFORM_MODE) var c = a.createEncryptor; else c = a.createDecryptor,
                 this._minBufferSize = 1;
             this._mode = c.call(a, this, b && b.words);
         },
         _doProcessBlock:function(a, b) {
             this._mode.processBlock(a, b);
         },
         _doFinalize:function() {
             var a = this.cfg.padding;
             if (this._xformMode == this._ENC_XFORM_MODE) {
                 a.pad(this._data, this.blockSize);
                 var b = this._process(!0);
             } else b = this._process(!0), a.unpad(b);
             return b;
         },
         blockSize:4
     });
     var n = d.CipherParams = l.extend({
         init:function(a) {
             this.mixIn(a);
         },
         toString:function(a) {
             return (a || this.formatter).stringify(this);
         }
     }), b = (p.format = {}).OpenSSL = {
         stringify:function(a) {
             var b = a.ciphertext;
             a = a.salt;
             return (a ? s.create([ 1398893684, 1701076831 ]).concat(a).concat(b) :b).toString(r);
         },
         parse:function(a) {
             a = r.parse(a);
             var b = a.words;
             if (1398893684 == b[0] && 1701076831 == b[1]) {
                 var c = s.create(b.slice(2, 4));
                 b.splice(0, 4);
                 a.sigBytes -= 16;
             }
             return n.create({
                 ciphertext:a,
                 salt:c
             });
         }
     }, a = d.SerializableCipher = l.extend({
         cfg:l.extend({
             format:b
         }),
         encrypt:function(a, b, c, d) {
             d = this.cfg.extend(d);
             var l = a.createEncryptor(c, d);
             b = l.finalize(b);
             l = l.cfg;
             return n.create({
                 ciphertext:b,
                 key:c,
                 iv:l.iv,
                 algorithm:a,
                 mode:l.mode,
                 padding:l.padding,
                 blockSize:a.blockSize,
                 formatter:d.format
             });
         },
         decrypt:function(a, b, c, d) {
             d = this.cfg.extend(d);
             b = this._parse(b, d.format);
             return a.createDecryptor(c, d).finalize(b.ciphertext);
         },
         _parse:function(a, b) {
             return "string" == typeof a ? b.parse(a, this) :a;
         }
     }), p = (p.kdf = {}).OpenSSL = {
         execute:function(a, b, c, d) {
             d || (d = s.random(8));
             a = w.create({
                 keySize:b + c
             }).compute(a, d);
             c = s.create(a.words.slice(b), 4 * c);
             a.sigBytes = 4 * b;
             return n.create({
                 key:a,
                 iv:c,
                 salt:d
             });
         }
     }, c = d.PasswordBasedCipher = a.extend({
         cfg:a.cfg.extend({
             kdf:p
         }),
         encrypt:function(b, c, d, l) {
             l = this.cfg.extend(l);
             d = l.kdf.execute(d, b.keySize, b.ivSize);
             l.iv = d.iv;
             b = a.encrypt.call(this, b, c, d.key, l);
             b.mixIn(d);
             return b;
         },
         decrypt:function(b, c, d, l) {
             l = this.cfg.extend(l);
             c = this._parse(c, l.format);
             d = l.kdf.execute(d, b.keySize, b.ivSize, c.salt);
             l.iv = d.iv;
             return a.decrypt.call(this, b, c, d.key, l);
         }
     });
 }();
 
 (function() {
     for (var u = QMCJS, p = u.lib.BlockCipher, d = u.algo, l = [], s = [], t = [], r = [], w = [], v = [], b = [], x = [], q = [], n = [], a = [], c = 0; 256 > c; c++) a[c] = 128 > c ? c << 1 :c << 1 ^ 283;
     for (var e = 0, j = 0, c = 0; 256 > c; c++) {
         var k = j ^ j << 1 ^ j << 2 ^ j << 3 ^ j << 4, k = k >>> 8 ^ k & 255 ^ 99;
         l[e] = k;
         s[k] = e;
         var z = a[e], F = a[z], G = a[F], y = 257 * a[k] ^ 16843008 * k;
         t[e] = y << 24 | y >>> 8;
         r[e] = y << 16 | y >>> 16;
         w[e] = y << 8 | y >>> 24;
         v[e] = y;
         y = 16843009 * G ^ 65537 * F ^ 257 * z ^ 16843008 * e;
         b[k] = y << 24 | y >>> 8;
         x[k] = y << 16 | y >>> 16;
         q[k] = y << 8 | y >>> 24;
         n[k] = y;
         e ? (e = z ^ a[a[a[G ^ z]]], j ^= a[a[j]]) :e = j = 1;
     }
     var H = [ 0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54 ], d = d.AES = p.extend({
         _doReset:function() {
             for (var a = this._key, c = a.words, d = a.sigBytes / 4, a = 4 * ((this._nRounds = d + 6) + 1), e = this._keySchedule = [], j = 0; j < a; j++) if (j < d) e[j] = c[j]; else {
                 var k = e[j - 1];
                 j % d ? 6 < d && 4 == j % d && (k = l[k >>> 24] << 24 | l[k >>> 16 & 255] << 16 | l[k >>> 8 & 255] << 8 | l[k & 255]) :(k = k << 8 | k >>> 24,
                     k = l[k >>> 24] << 24 | l[k >>> 16 & 255] << 16 | l[k >>> 8 & 255] << 8 | l[k & 255],
                     k ^= H[j / d | 0] << 24);
                 e[j] = e[j - d] ^ k;
             }
             c = this._invKeySchedule = [];
             for (d = 0; d < a; d++) j = a - d, k = d % 4 ? e[j] :e[j - 4], c[d] = 4 > d || 4 >= j ? k :b[l[k >>> 24]] ^ x[l[k >>> 16 & 255]] ^ q[l[k >>> 8 & 255]] ^ n[l[k & 255]];
         },
         encryptBlock:function(a, b) {
             this._doCryptBlock(a, b, this._keySchedule, t, r, w, v, l);
         },
         decryptBlock:function(a, c) {
             var d = a[c + 1];
             a[c + 1] = a[c + 3];
             a[c + 3] = d;
             this._doCryptBlock(a, c, this._invKeySchedule, b, x, q, n, s);
             d = a[c + 1];
             a[c + 1] = a[c + 3];
             a[c + 3] = d;
         },
         _doCryptBlock:function(a, b, c, d, e, j, l, f) {
             for (var m = this._nRounds, g = a[b] ^ c[0], h = a[b + 1] ^ c[1], k = a[b + 2] ^ c[2], n = a[b + 3] ^ c[3], p = 4, r = 1; r < m; r++) var q = d[g >>> 24] ^ e[h >>> 16 & 255] ^ j[k >>> 8 & 255] ^ l[n & 255] ^ c[p++], s = d[h >>> 24] ^ e[k >>> 16 & 255] ^ j[n >>> 8 & 255] ^ l[g & 255] ^ c[p++], t = d[k >>> 24] ^ e[n >>> 16 & 255] ^ j[g >>> 8 & 255] ^ l[h & 255] ^ c[p++], n = d[n >>> 24] ^ e[g >>> 16 & 255] ^ j[h >>> 8 & 255] ^ l[k & 255] ^ c[p++], g = q, h = s, k = t;
             q = (f[g >>> 24] << 24 | f[h >>> 16 & 255] << 16 | f[k >>> 8 & 255] << 8 | f[n & 255]) ^ c[p++];
             s = (f[h >>> 24] << 24 | f[k >>> 16 & 255] << 16 | f[n >>> 8 & 255] << 8 | f[g & 255]) ^ c[p++];
             t = (f[k >>> 24] << 24 | f[n >>> 16 & 255] << 16 | f[g >>> 8 & 255] << 8 | f[h & 255]) ^ c[p++];
             n = (f[n >>> 24] << 24 | f[g >>> 16 & 255] << 16 | f[h >>> 8 & 255] << 8 | f[k & 255]) ^ c[p++];
             a[b] = q;
             a[b + 1] = s;
             a[b + 2] = t;
             a[b + 3] = n;
         },
         keySize:8
     });
     u.AES = p._createHelper(d);
 })();
 
 
 QMCJS.mode.ECB = (function () {
     var ECB = QMCJS.lib.BlockCipherMode.extend();
 
     ECB.Encryptor = ECB.extend({
         processBlock: function (words, offset) {
             this._cipher.encryptBlock(words, offset);
         }
     });
 
     ECB.Decryptor = ECB.extend({
         processBlock: function (words, offset) {
             this._cipher.decryptBlock(words, offset);
         }
     });
 
     return ECB;
 }());
 
 function QMEncrypt(word){
     var key = QMCJS.enc.Utf8.parse(QMdecrypt("/Q5XF4CITE54H9PPn/TKXw==","QM"));
 
     var srcs = QMCJS.enc.Utf8.parse(word);
     var encrypted = QMCJS.AES.encrypt(srcs, key, {mode:QMCJS.mode.ECB,padding: QMCJS.pad.Pkcs7});
     return encrypted.toString();
 }
 function QMDecrypt(word){
     var key = QMCJS.enc.Utf8.parse(QMdecrypt("/Q5XF4CITE54H9PPn/TKXw==","QM"));
 
     var decrypt = QMCJS.AES.decrypt(word, key, {mode:QMCJS.mode.ECB,padding: QMCJS.pad.Pkcs7});
     return QMCJS.enc.Utf8.stringify(decrypt).toString();
 }
 function compareArr(property){
     return function(a,b){
         var value1 = a[property];
         var value2 = b[property];
         return value1 - value2;
     }
 }
 
 function getIceServerList(param){
     try {
         var url = "https://i.ehomecare.vip/web/config/getice";
         if(!!param){
             url = "https://"+param+"/web/config/getice";
         }
         $.ajax({
             url:url,
             type:"get",
             dataType:"jsonp",
             jsonp:"callback",
             beforeSend:function() {},
             success:function(data) {
                 try {
                     var res = data;
                     if (res.resultInt == 1) {
                         for(var i in res.resultObj.iceServers) {
                             var server = {};
                             server.username = QMDecrypt(res.resultObj.iceServers[i].username);
                             server.password = QMDecrypt(res.resultObj.iceServers[i].password);
                             server.uri = QMDecrypt(res.resultObj.iceServers[i].uri);
                             // serverList.push(server);
                             RTCVideo.addVideoServer(server);
                         }
                     } else {
                        console.log(res.resultInt+"");
                     }
                 } catch (e) {
                     console.log("error---->" + e.message);
                 }
             },
             complete:function(XMLHttpRequest, textStatus) {
             },
             error:function(XMLHttpRequest, textStatus, errorThrown) {
                 console.log("error---:"+textStatus);
             }
         });
     } catch (exc) {
         console.log("getserverlist error--:" + exc.message);
     }
 }